
#include "JavaVmInitArg.h"
#include "jni.h"

#include <windows.h>

using namespace Pan;

JavaVmInitArg::JavaVmInitArg(unsigned int max_option_count) : max_option_count(max_option_count)
{
    this->args = new JavaVMInitArgs[1];
    this->options = new JavaVMOption[this->max_option_count];

    JavaVMInitArgs *const args(reinterpret_cast<JavaVMInitArgs *>(this->args));
    JavaVMOption *const options(reinterpret_cast<JavaVMOption *>(this->options));

    // 结构体清零
    ::memset(args, 0, sizeof(JavaVMInitArgs));
    ::memset(options, 0, sizeof(JavaVMOption) * this->max_option_count);

    // Java 虚拟机初始化参数
    args->ignoreUnrecognized = JNI_TRUE;
    args->version = JNI_VERSION_1_8;
    args->nOptions = 0;
    args->options = options;
}

JavaVmInitArg::~JavaVmInitArg()
{
    JavaVMInitArgs *const args(reinterpret_cast<JavaVMInitArgs *>(this->args));
    JavaVMOption *const options(reinterpret_cast<JavaVMOption *>(this->options));

    // 释放内存
    for (jint i = 0; i < args->nOptions; i++)
    {
        if (options[i].optionString != nullptr)
        {
            delete[] options[i].optionString;
            options[i].optionString = nullptr;
        }
    }

    if (args != nullptr)
    {
        delete[] args;
        this->args = nullptr;
    }

    if (options != nullptr)
    {
        delete[] options;
        this->options = nullptr;
    }
}

bool JavaVmInitArg::add_option(const char *option)
{
    // 空指针检查
    if (option == nullptr)
        return false;

    JavaVMInitArgs *const args(reinterpret_cast<JavaVMInitArgs *>(this->args));
    JavaVMOption *const options(reinterpret_cast<JavaVMOption *>(this->options));

    // 检查是否满了
    if (static_cast<decltype(this->max_option_count)>(args->nOptions) >= this->max_option_count)
    {
        args->nOptions = this->max_option_count;
        return false;
    }

    // 计算字符串长度
    unsigned long len = 0;
    while (option[len] != '\0')
    {
        len++;
    }

    // 多一个字节要保存结束符
    char *t = new char[len + 1];
    if (t == nullptr)
    {
        return false; // 内存分配失败
    }

    // 字符串复制
    for (unsigned long i = 0; i < len + 1; i++)
    {
        t[i] = option[i];
    }

    options[args->nOptions].optionString = t;
    args->nOptions++;
    return true;
}
